package uem

import (
	"sync"
)

type Queue struct {
	mutex      sync.Mutex
	cond       *sync.Cond
	buffer     []interface{}
	terminated bool
	exit       bool
}

func NewQueue() *Queue {
	q := &Queue{}
	q.cond = sync.NewCond(&q.mutex)
	q.exit = false
	return q
}
func (q *Queue) Produce(data interface{}) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.buffer = append(q.buffer, data)
	// 唤醒等待的消费者
	q.cond.Signal()
}
func (q *Queue) Consume(newSlice *[]interface{}) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	// 等待数据可用
	if len(q.buffer) == 0 && !q.exit {
		q.cond.Wait()
	}
	if len(q.buffer) > 0 {
		*newSlice = append(*newSlice, q.buffer...)
		q.buffer = q.buffer[:0]
	}

	//log.Printf("Consume: %v", len(q.buffer))
}
func (q *Queue) Notify() {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.terminated = true
	// 唤醒所有等待的消费者
	q.cond.Broadcast()
}

func (q *Queue) Exit() {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.exit = true
	q.cond.Broadcast()
}

func (q *Queue) IsExit() bool {
	return q.exit
}

func (q *Queue) Len() int {
	return len(q.buffer)
}
